import urlparse
import pprint
import urllib
import urllib2
from Util.Serialization import serialize
from Util.Serialization import deserialize
from Util.odict import odict

class Capability:
    #Describes the specific attributes by which to filter deals.
    Unknown = 0
    #The capabilities of the deal are not known, or unknown even
    Favorite = 1
    #Favorited by The Dealmap Deal Editors
    HasTransaction = 2
    #Involves some kind of purchase
    Features = 4
    #This deal is featured on the Dealmap
    Exclusive = 8
    #This deal is exclusively available only at The Dealmap
    FiftyPercentOrMore = 16
    #This deal has 50 or more % savings
    CanBePrinted = 32
    #This is a printable coupon
    
class CenterdActivity:
    """
    Describes the different filters availble based on a specific activity 
    type or interest
    """
    Unknown = 0
    Kids = 1
    Group = 8 
    Romantic = 16
    Casual = 64
    Fun = 512
    LateNight = 16384
    Outdoor = 32768
    
    
class ProposedDeal:
    """
    Represents a proposed deal to be submitted to the dealmap
    contains a number of mandatory and optional fields
    """
    def __init__(self,
        title, 
        expirationDate, 
        addedBy, 
        country, 
        city, 
        state, 
        businessName, 
        streetAddress,
        latitude,
        longitude,
        id = "",
        details = "",
        restrictions = "",
        effectiveDate = "",
        url ="",
        isExclusive = 0,
        firstName = "",
        lastName ="",
        isOwner = "false",
        socialNetworkId = "",
        businessDetails="",
        photoType ="",
        photoContent = "",
        tags = "",
        category = "",
        styles = 0):
            # Mandatory fields
            self.title = title
            self.expirationDate = expirationDate
            self.addedBy = addedBy
            self.country = country
            self.city= city
            self.state = state
            self.businessName = businessName
            self.streetAddress = streetAddress
            self.latitude = latitude
            self.longitude = longitude
            # optional fields
            self.id = id
            self.details = details
            self.restrictions = restrictions
            self.effectiveDate = effectiveDate
            self.url = url
            self.isExclusive = isExclusive
            self.firstName = firstName
            self.lastName =lastName
            self.isOwner = isOwner
            self.socialNetworkId = socialNetworkId
            self.businessDetails= businessDetails
            self.photoType = photoType
            self.photoContent = photoContent
            self.tags = tags
            self.category = category
            self.styles = styles

    def get_xml_dictionary(self):
        dealdetails = odict(
        # namespace information
        [("xmlns:xsd", "http://www.w3.org/2001/XMLSchema"),("xmlns:i","http://www.w3.org/2001/XMLSchema-instance"), ("xmlns","http://thedealmap.com/api") ,
            #Fields to add to xml
            ("ID",[self.id]),
            ("Title",[self.title]),
            ("Details",[self.details]),
            ("Restrictions",[self.restrictions]),
            ("EffectiveDate",[self.effectiveDate.strftime("%Y-%m-%dT%H:%M:%S")]),
            ("ExpirationDate",[self.expirationDate.strftime("%Y-%m-%dT%H:%M:%S")]),
            ("Url",[self.url]),
            ("IsExclusive",[str(self.isExclusive)]),
            ("FirstName",[self.firstName]),
            ("LastName",[self.lastName]),
            ("IsOwner",[self.isOwner]),
            ("AddedBy",[self.addedBy]),
            ("SocialNetworkID",[str(self.socialNetworkId)]),
            ("DailDealsEmailOK",["false"]),
            ("StreetAddress",[self.streetAddress]),
            ("Latitude",[str(self.latitude)]),
            ("Longitude",[str(self.longitude)]),
            ("City",[self.city]),
            ("State",[self.state]),
            ("Country",[self.country]),
            ("BusinessName",[self.businessName]),
            ("BusinessDetails",[self.businessDetails]),
            ("PhotoType",[self.photoType]),
            ("PhotoContent",[self.photoContent]),
            ("Tags",[self.tags]),
            ("Category",[self.category]),
            ("Styles",[str(self.styles)]),
            ("VendorId",[]),
            ("DealSource",[str(0)])
        ])

        deal = {"AddDealRequest": dealdetails}

        return deal

class Service:
    __apikey = ""
    __dealmapUrls = {
                   "search_deals":"http://api.thedealmap.com/search/deals/",
                   "search_businesses":"http://api.thedealmap.com/search/businesses/",
                   "add_deal":"http://api.thedealmap.com/deals/"
                   }
    def __init__(self, apikey):
        """
        Creates a new instance of the dealmap client library and
        sets the apkikey to be used in requests.
        """
        self.__apikey = apikey
        
    def search_deals(self, activities, capabilities, expirationDate, location, query="*", distance=5.0, startIndex=0, pageSize=20):
        searchDeals = self.__build_get_url(self.__dealmapUrls["search_deals"],
                                         l=location,
                                         q=query,
                                         d=distance,
                                         si=startIndex,
                                         ps=pageSize,
                                         a=activities,
                                         c=capabilities,
                                         ed=expirationDate,
                                         key=self.__apikey
                                         )
        
        result = self.__dealmap_get_request(searchDeals)
        obj = deserialize(result)
        return obj

    def search_business_listings(self, activities, location, query="*", distance=5.0, startIndex=0, pageSize=20):
        searchBussinesses = self.__build_get_url(
                                               self.__dealmapUrls["search_businesses"],
                                               l=location,
                                               q=query,
                                               d=distance,
                                               si=startIndex,
                                               ps=pageSize,
                                               a=activities,
                                               key=self.__apikey
                                               )
        
        result = self.__dealmap_get_request(searchBussinesses)
        obj = deserialize(result)
        return obj
    
    def get_deal_details(self, dealId):
        deal = self.__dealmapUrls["search_deals"] + dealID
        obj = deserialize(deal)
        return obj
    
    def submit_deal(self, proposedDeal):
        deal = proposedDeal.get_xml_dictionary()
        print(deal)
        xml = serialize(deal)
        print(xml)
        result = self.__post_data(self.__dealmapUrls["add_deal"], xml)
        
        print(result)
        obj = deserialize(result)
        return obj;
    
    def __build_get_url(self, url, **kwargs):
        url = url + "?" + urllib.urlencode(kwargs)
        print url
        return url
    
    def __dealmap_get_request(self, url):
        """
        Issues a HTTP get request to the Dealmap endpoint sepcified in the 
        url parameter.
        """
        data = urllib2.urlopen(url).read()
        return data
    
    def __post_data(self, url, data):
        headers = {
           "Content-type": "application/xml; charset=utf-8",
           "Content-length": len(data)
           }
        request = urllib2.Request(url, data, headers)
    
        try:
            response = urllib2.urlopen(request).read()
    
        except urllib2.HTTPError, e:
            response = {
                       "Http Error Code" : str(e.code),
                       "Error Msg": e.msg,
                       "Returned Headers" : urllib.unquote_plus(pprint.pformat(e.headers)),
                       "Inner Html": urllib.unquote_plus(e.fp.read())
                       }
    
        return response
